﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNASpelProjekt
{
    /// <summary>
    /// Klass for the Ultros boss
    /// </summary>
    public class Ultros : EnemyActor
    {
        #region protected methods

        /// <summary>
        /// performs new state initialization and change state
        /// </summary>
        /// <param name="s">The StateType to change to</param>
        protected override void changeState(_state s)
        {
            stateTime = 0;
            switch(s)
            {
                case _state.underwater:
                    Hidden = true;
                    X = -20;
                    Y = -20;                    
                    stateTimeLimit = (rnd.Next() % 1000) + 2000;
                    break;

                case _state.movingUp:
                    //set random jump up spot
                    int temp = rnd.Next() % 2;
                    switch (temp)
                    {
                        case 0:
                            Facing = _Facing.right;
                            X = 48;
                            break;
                        case 1:
                            Facing = _Facing.left;
                            X = 525;
                            break;
                    }
                    Y = 411;
                    desty = 150;                                  
                    break;

                case _state.shooting:
                    stateTimeLimit = 500;                  
                    break;

                case _state.movingDown:
                    desty = 411;
                    break;
                    
                case _state.dying:
                    Hidden = true;
                    Game1.map.animations.Add(new DeathAnimationActor(Game1.deathImage1, X, Y));                    
                    stateTimeLimit = 1500;
                    break;
            }
            state = s;
        }

        /// <summary>
        /// Handles shooting
        /// </summary>
        /// <param name="angle">The shot's base angle</param>
        protected void shoot(double angle)
        {
            int shotOffset = 0;
            double angleOffset = 0;
            Game1.ultrosShotSound.Play();
            switch (Facing)
            {
                case _Facing.left:
                    shotOffset = -(Game1.ultrosShotImage.Width);
                    angleOffset = 0.06;                    
                    break;
                case _Facing.right:
                    shotOffset = Bounds.Width;
                    angle = (-angle) + 3;
                    angleOffset = -0.06;
                    break;
            }
            Game1.map.bullets.Add(new UltrosShot(X + shotOffset, Y + (Bounds.Width / 2) - (Game1.ultrosShotImage.Height / 2), Math.PI * angle));
            Game1.map.bullets.Add(new UltrosShot(X + shotOffset, Y + (Bounds.Width / 2) - (Game1.ultrosShotImage.Height / 2), Math.PI * (angle + angleOffset)));
            Game1.map.bullets.Add(new UltrosShot(X + shotOffset, Y + (Bounds.Width / 2) - (Game1.ultrosShotImage.Height / 2), Math.PI * (angle - angleOffset)));
        }

        #endregion

        #region public methods

        /// <summary>
        /// Updates the Ultros in the game.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            switch (state)
            {
                case _state.underwater:
                    stateTime += gameTime.ElapsedGameTime.Milliseconds;
                    if (stateTime >= stateTimeLimit)    //time limit reached, change state
                    {
                        changeState(_state.movingUp);
                    }
                    break;

                case _state.movingUp:
                    Hidden = false;
                    Y -= 6;
                    if (desty > Y)  //moved past destination, change state
                    {
                        changeState(_state.shooting);
                    }
                    break;

                case _state.shooting:
                    Hidden = false;
                    stateTime += gameTime.ElapsedGameTime.Milliseconds;

                    if (stateTime >= stateTimeLimit && stateTimeLimit == 500)
                    {
                        shoot(1.16);
                        stateTimeLimit = 1500;
                    }
                    else if (stateTime >= stateTimeLimit && stateTimeLimit == 1500)
                    {
                        shoot(1.31);
                        stateTimeLimit = 2500;
                    }
                    else if (stateTime >= stateTimeLimit && stateTimeLimit == 2500)
                    {
                        shoot(1.16);
                        stateTimeLimit = 3200;
                    }
                    else if (stateTime >= stateTimeLimit && stateTimeLimit == 3200) //time limit reached, change state
                    {
                        changeState(_state.movingDown);
                    }
                    break;

                case _state.movingDown:
                    Hidden = false;
                    Y += 6;
                    if (desty < Y)  //moved past destination, change state
                    {                                    
                        changeState(_state.underwater);
                    }
                    break;
                case _state.dying:
                    stateTime += gameTime.ElapsedGameTime.Milliseconds;
                    if (stateTime >= stateTimeLimit)
                    {
                        Game1.map.enemiesToRemove.Add(this);
                        Game1.quit = true;
                    }                    
                    break;
            }
        }

        #endregion

        #region constructors

        /// <summary>
        /// Creates an Ultros enemy object
        /// </summary>
        /// <param name="x">Ultros' x-coordinate</param>
        /// <param name="y">Ultros' y-coordinate</param>
        /// <param name="facing">Ultros' facing</param>
        public Ultros(int x = 0, int y = 0, _Facing facing = _Facing.right) : base(Game1.ultrosImage, x, y, facing)
        {
            rnd = new Random();
            Health = 20;
            CollisionDamage = 6;

            state = _state.movingUp;
            stateTime = -500;
            stateTimeLimit = 500;
            desty = 150;
            Hidden = false;
            stateSet = true;
        }

        #endregion
    }
}
